/*
 *  JDiv - API for Multimedia Application
 *  http://jdiv.sourceforge.net 
 *  ------------------------------------
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

package com.jdiv;

import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.jdiv.internalClasses.JDivImage;
import com.jdiv.internalClasses.SceneReserved;
import com.jdiv.internalClasses.TextImage;
import com.jdiv.kernel.JDivResources;
import com.jdiv.kernel.JDivSystem;

/**
 * This class handles the container scene of graphic objects: Process, Write.
 */

public class Scene {

	int   idScene;       // Identificador de la escena
	
	int   depth;         // Profundidad a la que debe mostrarse la escena
	
	float alpha;         // Grado de transparencia de la escena 
	
	int   idBackground;  // Identificador de la imagen
	
	boolean cleaner;     // Si esta activo o no el limpiador de pantalla
	
	SceneReserved reserved;
	
	/**
	  * Create a new scene with the width and height set {@link com.jdiv.functions.FunctionsScene#setMode(int, int)}
	  */
	
	public Scene( )
	{
		this.idScene = JDivResources.listScenes.listScenes.size();
		
		cleaner = true;
		
		reserved = new SceneReserved();
		
		reserved.width  = JDivSystem.scrWidthSet;
		reserved.height = JDivSystem.scrHeightSet;
		
		reserved.stage  = new Stage(reserved.width, reserved.height, false);
		
	
		// Inicializo el TextManager(Creacion de regiones para los caracteres).
//		JDiv.textManager.init();
		
		setCenterXY( reserved.width/2, reserved.height/2 );
		
		depth = 0; 
		
		alpha = 1; // Opaco
		
		JDivResources.listScenes.sceneAdd(this);
	}
	
	/**
	  * @return Reserved for the use of Scene.
	  */
	
	public SceneReserved getReserved(){
		return reserved;
	}
	
	/**
	 * @return Number identifier of Scene.
	 */
	
	public int getIdScene(){
		return idScene;
	}
	
	/**
	 * Sets center X of scene.
	 * @param centerX Center X of scene.
	 */
	
	public void setCenterX( float centerX ){
		reserved.centerXSet = centerX;
	}
	
	/**
	 * Sets center Y of scene.
	 * @param centerY Center Y of scene.
	 */
	
	public void setCenterY( float centerY ){
		reserved.centerYSet = centerY;
	}
	
	/**
	 * Sets center X, Y of scene. 
	 * @param centerX Center X of scene.
	 * @param centerY Center Y of scene.
	 */
	
	public void setCenterXY( float centerX, float centerY ){
		setCenterX(centerX);
		setCenterY(centerY);
	}
	
	/**
	 * Sets scale of Scene.
	 * @param scale Scale of Scene, initially its value is 1 that means 100%.
	 */
	
	public void setScale( float scale ){
		
		if( scale > 0 )
		 reserved.scaleSet = scale;
		else
		 reserved.scaleSet = 0;
		
	}
	
	/**
	  * Change the scale of Scene in set time.
	  * @param scale Scale of Scene.
	  * @param timeSeconds Time that changes scale of Scene.
	  */
	
	public void setScale( float scale, float timeSeconds ){
		setScale( scale, timeSeconds, null );
	}
	
	/**
	  * Change the scale of Scene in set time.
	  * @param scale Scale of Scene.
	  * @param timeSeconds Time that changes scale of Scene.
	  * @param interpolation Use Interpolation of LibGdx for the changes the scale of Scene.
	  */
	  
	 public void setScale( float scale, float timeSeconds, Interpolation interpolation ){
        
		 if( scale >= 0 ){
		  if( timeSeconds == 0 )
			  reserved.scaleSet = scale;
			 
		  if( timeSeconds >= 0 )
			  reserved.scaleTime.setFloatTimed(reserved.scaleSet, scale, timeSeconds, interpolation);
		 }
	 }
	 
	 /**
	    * @return True if you are doing a scale, false otherwise.
		*/
		 
	  public boolean isScale(){
	 	 return reserved.scaleTime.isChanging(); 
	  }
	
	/**
	 * @return Scale of Scene.
	 */
	
	public float getScale(){
		return reserved.scale;
	}
	
	/**
	  * Set Scene depth to be displayed.
	  * @param depth Depth to be displayed.
	  */
	 
	 public void setDepth( int depth ){
		 
		 JDivResources.listScenes.sceneListSort = true;
		 this.depth = depth;
	 }
	 
	 /**
	  * Gets Scene depth.
	  * @return Depth of scene.
	  */
	 
	 public int getDepth( ){
		 return this.depth;
	 }
	 
	 /**
	  * Set transparent Level of scene: 1 opaque to 0 unseen, initially its value is 1 opaque.
	  * @param alpha transparent Level of Scene, default is 1 opaque.
	  */
	 
	 public void setAlpha( float alpha ){
		 setAlpha( alpha, 0, null );
	 }
	 
	 /**
	  * Set transparent Level of scene: 1 opaque to 0 unseen, initially its value is 1 opaque.
	  * @param alpha transparent Level of Scene, default is 1 opaque.
	  * @param timeSeconds Time that changes the level of transparency.
      */
	 
	 public void setAlpha( float alpha, float timeSeconds ){
		 setAlpha( alpha, timeSeconds, null );
	 }
	 
	 /**
	  * Set transparent Level of scene: 1 opaque to 0 unseen, initially its value is 1 opaque.
	  * @param alpha transparent Level of Scene, default is 1 opaque.
	  * @param timeSeconds Time that changes the level of transparency.
      * @param interpolation Use Interpolation of LibGdx for the changes the level of transparency.
	  */
	 
	 public void setAlpha( float alpha, float timeSeconds, Interpolation interpolation ){
		 
         float a = alpha;
		 
		 if( alpha > 1 ) a = 1;
		 if( alpha < 0 ) a = 0;
		 
		 if( timeSeconds == 0 )
			 this.alpha = a;
		  
		 if( timeSeconds > 0 )
			 reserved.alphaTime.setFloatTimed(this.alpha, a, timeSeconds, interpolation);	  
	  }
	 
	 /**
	  * Set Scroll X for Scene.
	  * @param scrollX Scroll X for Scene.
	  */
	 
	 public void setScrollX( float scrollX ){
		 setScrollX( scrollX, 0, null );
	 }
	 
	 /**
	  * Set Scroll X for Scene.
	  * @param scrollX Scroll X for Scene.
	  * @param timeSeconds Time to set of Scene.
	  */
	 
	 public void setScrollX( float scrollX, float timeSeconds ){
		 setScrollX( scrollX, timeSeconds, null );
	 }
	 
	 /**
	   * Set Scroll X for Scene.
	   * @param scrollX Scroll X for Scene.
	   * @param timeSeconds Time to set of Scene.
	   * @param interpolation Use Interpolation of LibGdx to set scroll of Scene.
	   */
	  
	  public void setScrollX( float scrollX, float timeSeconds, Interpolation interpolation ){
	    
		  if( timeSeconds >= 0 ){
			  reserved.scrollXSet = scrollX;
			  reserved.scrollXTime.setFloatTimed(reserved.scrollX, reserved.scrollXSet, timeSeconds, interpolation);
		  }
	  }
	  
	  /**
	    * @return True if you are doing a scroll in X, false otherwise.
		*/
		 
	  public boolean isScrollX(){
	 	 return reserved.scrollXTime.isChanging(); 
	  }
	 
	 /**
	  * Set Scroll Y for Scene.
	  * @param scrollY Scroll Y for Scene.
	  */
	 
	 public void setScrollY( float scrollY ){
		 setScrollY( scrollY, 0, null );
	 }
	 
	 /**
	  * Set Scroll Y for Scene.
	  * @param scrollY Scroll Y for Scene.
	  * @param timeSeconds Time to set of Scene.
	  */
	 
	 public void setScrollY( float scrollY, float timeSeconds ){
		 setScrollY( scrollY, timeSeconds, null );
	 }
	 
	 /**
	   * Set Scroll Y for Scene.
	   * @param scrollY Scroll Y for Scene.
	   * @param timeSeconds Time to set of Scene.
	   * @param interpolation Use Interpolation of LibGdx to set scroll of Scene.
	   */
	  
	  public void setScrollY( float scrollY, float timeSeconds, Interpolation interpolation ){
	    
		  if( timeSeconds >= 0 ){
			  reserved.scrollYSet = scrollY;
			  reserved.scrollYTime.setFloatTimed(reserved.scrollY, reserved.scrollYSet, timeSeconds, interpolation);
		  }
	  }
	  
	  /**
	    * @return True if you are doing a scale in Y, false otherwise.
		*/
		 
	  public boolean isScrollY(){
	 	 return reserved.scrollYTime.isChanging(); 
	  }
	 
	 /**
	  * @return X Scroll for Scene.
	  */
	 
	 public float getScrollX(){
		 return reserved.scrollX;
	 }
	 
	 /**
	  * @return Y Scroll for Scene.
	  */
	 
	 public float getScrollY(){
		 return reserved.scrollY;
	 }
	 
	 /**
	  * @return Alpha transparent Level of Scene, default is 1 opaque.
	  */
	 
	 public float getAlpha(){
		 return this.alpha;
	 }
	 
	 /**
	  * @return True if you are doing a fade alpha, false otherwise.
	  */
	 
	 public boolean isFading(){
		 return reserved.alphaTime.isChanging(); 
	 }
	
	/**
	 * @return Stage for Scene, Class of LibGdx Stage.
	 */
	
	public Stage getStage(){
		return reserved.stage;
	}
	
	/**
	  * @return Width of Scene.
	  */
	
	public float getWidth(){
		return reserved.width;
	}
	
	/**
	  * @return Height of Scene.
	  */
	
	public float getHeight(){
		return reserved.height;
	}
	
	/**
	  * Sets the Scene background.
	  * @param idBackground Number identifier of Image.
	  */
	
	public void setBackground(int fileId, int idBackground ){
		
		this.idBackground       = idBackground;
		reserved.backgroundSet  = JDivResources.listTextures.getJDivImage(fileId,idBackground);
		
	}
	
	/**
	 * @return Number identifier of Background Image.
	 */
	
	public int getBackground(){
		return idBackground;
	}
	
	/**
	  * Deleting a scene from the scene list.
	  */
	
	public void delete(){
		JDivResources.listScenes.sceneDelete(this);
	}

	/**
	 * We release the memory allocated for the Scene.	
	 */
	
	public void dispose(){
		if( reserved.stage != null ){
			JDivResources.listScenes.sceneDelete(this);
			
			reserved.stage.clear();
			reserved.stage.dispose();
			reserved.stage = null;
		}
	}
	
	/**
	 * Active Scene cleaner.
	 */
	
	public void setCleanerOn(){
		cleaner = true;
	}
	
	/**
	 * Disable Scene cleaner.
	 */
	
	public void setCleanerOff(){
		cleaner = false;
	}
	
	/**
	 * Checks if the Scene cleaner is active or not.
	 * @return True if active and false otherwise.
	 */
	
	public boolean isActiveCleaner(){
		return cleaner;
	}
	
	/**
	 * Clean the Scene.
	 */
	
	public void clear(){
		if( reserved.stage != null ) 
			reserved.stage.clear();
	}
	
	/**
	 * Add an image to the scene.
	 * @param idImage Number identifier of image.
	 * @param x Position X at the scene.
	 * @param y Position Y at the scene.
	 * @param nWidth Number of images in width.
	 * @param nHeight Number of images in height.
	 */
	
	public void addImage(int fileId, int idImage, float x, float y, int nWidth, int nHeight ){
		
		if( reserved.stage == null ) return;
		
		setCleanerOff();
		
		JDivImage jdivImage = JDivResources.listTextures.getJDivImage(fileId, idImage);
		Image image = null;
		
		if( jdivImage != null )
			image = jdivImage.getImage(Const.MIRROR_NONE);
		
		if( image != null )
		 for( int w = 0; w < nWidth; w++ )
			for( int h = 0; h < nHeight; h++ ){
				Image img = jdivImage.getImage(Const.MIRROR_NONE);
				img.setX(x + image.getWidth()*w);
				img.setY(y + image.getHeight()*h);
				reserved.stage.addActor(img);
			}
	}
	
}
